FVP: Reclaim init code for the stack
authorDaniel Boulby <[email protected]>
Tue, 18 Sep 2018 10:52:49 +0000 (11:52 +0100)
committerAntonio Nino Diaz <[email protected]>
Wed, 3 Oct 2018 11:06:07 +0000 (12:06 +0100)
Map the initialization code for BL31 to overlap with the memory
required for the secondary cores stack. Once BL31 has been
initialized the memory can be remapped to RW data so that it can
be used for secondary cores stacks. By moving code from .text to
.text.init the size of the BL31 image is decreased by a page.

Split arm_common.ld.S into two linker scripts, one for tzc_dram
(arm_tzc_dram.ld.S) and one for reclaiming initialization code
(arm_reclaim_init.ld.S) so that platforms can chose which memory
regions they wish to include.

Change-Id: I648e88f3eda1aa71765744cf34343ecda9320b32
Signed-off-by: Daniel Boulby <[email protected]>
include/plat/arm/common/arm_common.ld.S [deleted file]
include/plat/arm/common/arm_def.h
include/plat/arm/common/arm_reclaim_init.ld.S [new file with mode: 0644]
include/plat/arm/common/arm_tzc_dram.ld.S [new file with mode: 0644]
include/plat/arm/common/plat_arm.h
plat/arm/board/fvp/include/plat.ld.S
plat/arm/board/fvp/platform.mk
plat/arm/common/arm_bl31_setup.c
plat/arm/common/arm_common.c
plat/arm/common/arm_common.mk

diff --git a/include/plat/arm/common/arm_common.ld.S b/include/plat/arm/common/arm_common.ld.S
deleted file mode 100644 (file)
index 3f6e29b..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#ifndef __ARM_COMMON_LD_S__
-#define __ARM_COMMON_LD_S__
-
-#include <xlat_tables_defs.h>
-
-MEMORY {
-    EL3_SEC_DRAM (rw): ORIGIN = ARM_EL3_TZC_DRAM1_BASE, LENGTH = ARM_EL3_TZC_DRAM1_SIZE
-}
-
-SECTIONS
-{
-       . = ARM_EL3_TZC_DRAM1_BASE;
-       ASSERT(. == ALIGN(PAGE_SIZE),
-       "ARM_EL3_TZC_DRAM_BASE address is not aligned on a page boundary.")
-       el3_tzc_dram (NOLOAD) : ALIGN(PAGE_SIZE) {
-       __EL3_SEC_DRAM_START__ = .;
-       *(arm_el3_tzc_dram)
-       __EL3_SEC_DRAM_UNALIGNED_END__ = .;
-
-       . = ALIGN(PAGE_SIZE);
-       __EL3_SEC_DRAM_END__ = .;
-       } >EL3_SEC_DRAM
-}
-
-#endif /* __ARM_COMMON_LD_S__ */
index 23cd12f51d1e1782e175f4d59a42a9e8b3c50b0c..8d81af960d8fb08f5fa83d38533340911cc0e15f 100644 (file)
  * The max number of regions like RO(code), coherent and data required by
  * different BL stages which need to be mapped in the MMU.
  */
-# define ARM_BL_REGIONS                        4
+#define ARM_BL_REGIONS                 5
 
 #define MAX_MMAP_REGIONS               (PLAT_ARM_MMAP_ENTRIES +        \
                                         ARM_BL_REGIONS)
diff --git a/include/plat/arm/common/arm_reclaim_init.ld.S b/include/plat/arm/common/arm_reclaim_init.ld.S
new file mode 100644 (file)
index 0000000..8f22170
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef ARM_RECLAIM_INIT_LD_S
+#define ARM_RECLAIM_INIT_LD_S
+
+SECTIONS
+{
+        .init __STACKS_START__ : {
+            . = . + PLATFORM_STACK_SIZE;
+            . = ALIGN(PAGE_SIZE);
+            __INIT_CODE_START__ = .;
+            /*
+             * Exclude PSCI initialization functions to ensure the init section
+             * does not become larger than the overlaid stack region
+             */
+            *(EXCLUDE_FILE (*psci_setup.o).text.init*)
+            __INIT_CODE_UNALIGNED__ = .;
+            .  = ALIGN(PAGE_SIZE);
+            __INIT_CODE_END__ = .;
+        } >RAM
+
+#ifdef BL31_PROGBITS_LIMIT
+    ASSERT(__INIT_CODE_END__ <= BL31_PROGBITS_LIMIT,
+            "BL31 init has exceeded progbits limit.")
+#endif
+
+#if RECLAIM_INIT_CODE
+    ASSERT(__INIT_CODE_END__ <= __STACKS_END__,
+        "Init code ends past the end of the stacks")
+#endif
+}
+
+#endif /* ARM_RECLAIM_INIT_LD_S */
diff --git a/include/plat/arm/common/arm_tzc_dram.ld.S b/include/plat/arm/common/arm_tzc_dram.ld.S
new file mode 100644 (file)
index 0000000..df951e1
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef ARM_TZC_DRAM_LD_S__
+#define ARM_TZC_DRAM_LD_S__
+
+#include <xlat_tables_defs.h>
+
+MEMORY {
+    EL3_SEC_DRAM (rw): ORIGIN = ARM_EL3_TZC_DRAM1_BASE, LENGTH = ARM_EL3_TZC_DRAM1_SIZE
+}
+
+SECTIONS
+{
+       . = ARM_EL3_TZC_DRAM1_BASE;
+       ASSERT(. == ALIGN(PAGE_SIZE),
+       "ARM_EL3_TZC_DRAM_BASE address is not aligned on a page boundary.")
+       el3_tzc_dram (NOLOAD) : ALIGN(PAGE_SIZE) {
+       __EL3_SEC_DRAM_START__ = .;
+       *(arm_el3_tzc_dram)
+       __EL3_SEC_DRAM_UNALIGNED_END__ = .;
+
+       . = ALIGN(PAGE_SIZE);
+       __EL3_SEC_DRAM_END__ = .;
+       } >EL3_SEC_DRAM
+}
+
+#endif /* ARM_TZC_DRAM_LD_S__ */
index 3f344abce0ab577ebcb92a72c1398f34176ead4a..d543894d7b1eeda815e5b099d3b99c8eb9469abd 100644 (file)
@@ -220,6 +220,12 @@ void arm_bl2_dyn_cfg_init(void);
 void arm_bl1_set_mbedtls_heap(void);
 int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size);
 
+/*
+ * Free the memory storing initialization code only used during an images boot
+ * time so it can be reclaimed for runtime data
+ */
+void arm_free_init_memory(void);
+
 /*
  * Mandatory functions required in ARM standard platforms
  */
index 24c3debd927c4571b70c73f540e138a450797fcb..f2a3ea6a43a1a9a9e6deb83860b63f7a8a21a437 100644 (file)
@@ -6,6 +6,7 @@
 #ifndef __PLAT_LD_S__
 #define __PLAT_LD_S__
 
-#include <arm_common.ld.S>
+#include <arm_tzc_dram.ld.S>
+#include <arm_reclaim_init.ld.S>
 
 #endif /* __PLAT_LD_S__ */
index 4cd6a24de676ca8a1746bbc3de9d6a787c087813..9bd3bde6579262e1205d3cbee93dcfaf8ac1caf6 100644 (file)
@@ -201,6 +201,9 @@ ENABLE_AMU                  :=      1
 # Enable dynamic mitigation support by default
 DYNAMIC_WORKAROUND_CVE_2018_3639       :=      1
 
+# Enable reclaiming of BL31 initialisation code for secondary cores stacks for FVP
+RECLAIM_INIT_CODE      :=      1
+
 ifeq (${ENABLE_AMU},1)
 BL31_SOURCES           +=      lib/cpus/aarch64/cortex_a75_pubsub.c    \
                                lib/cpus/aarch64/cortex_ares_pubsub.c   \
index c54566390b7971a4f3d54291acea94819724507c..ed2c3fbceed47415de35f37150f33622a42c66c1 100644 (file)
@@ -15,6 +15,8 @@
 #include <plat_arm.h>
 #include <platform.h>
 #include <ras.h>
+#include <utils.h>
+#include <arm_xlat_tables.h>
 
 /*
  * Placeholder variables for copying the arguments that have been passed to
@@ -35,10 +37,20 @@ CASSERT(BL31_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl31_base_overflows);
 #pragma weak bl31_plat_arch_setup
 #pragma weak bl31_plat_get_next_image_ep_info
 
-#define MAP_BL31_TOTAL MAP_REGION_FLAT(                        \
+#define MAP_BL31_TOTAL         MAP_REGION_FLAT(                        \
                                        BL31_BASE,                      \
                                        BL31_END - BL31_BASE,           \
                                        MT_MEMORY | MT_RW | MT_SECURE)
+#if RECLAIM_INIT_CODE
+IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE);
+IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_INIT_CODE_END);
+
+#define MAP_BL_INIT_CODE       MAP_REGION_FLAT(                        \
+                                       BL_INIT_CODE_BASE,              \
+                                       BL_INIT_CODE_END                \
+                                               - BL_INIT_CODE_BASE,    \
+                                       MT_CODE | MT_SECURE)
+#endif
 
 /*******************************************************************************
  * Return a pointer to the 'entry_point_info' structure of the next image for the
@@ -233,7 +245,28 @@ void arm_bl31_plat_runtime_setup(void)
 
        /* Initialize the runtime console */
        arm_console_runtime_init();
+#if RECLAIM_INIT_CODE
+       arm_free_init_memory();
+#endif
+}
+
+#if RECLAIM_INIT_CODE
+/*
+ * Zero out and make RW memory used to store image boot time code so it can
+ * be reclaimed during runtime
+ */
+void arm_free_init_memory(void)
+{
+       int ret = xlat_change_mem_attributes(BL_INIT_CODE_BASE,
+                               BL_INIT_CODE_END - BL_INIT_CODE_BASE,
+                               MT_RW_DATA);
+
+       if (ret != 0) {
+               ERROR("Could not reclaim initialization code");
+               panic();
+       }
 }
+#endif
 
 void __init bl31_platform_setup(void)
 {
@@ -255,6 +288,9 @@ void __init arm_bl31_plat_arch_setup(void)
 {
        const mmap_region_t bl_regions[] = {
                MAP_BL31_TOTAL,
+#if RECLAIM_INIT_CODE
+               MAP_BL_INIT_CODE,
+#endif
                ARM_MAP_BL_RO,
 #if USE_ROMLIB
                ARM_MAP_ROMLIB_CODE,
index ae06ef280a77758fff991460323c80c9fff856f7..a21d189e9b7606df65f68a2f62a7cfa0698ed0f6 100644 (file)
@@ -38,6 +38,7 @@ void arm_setup_romlib(void)
  * as an array specifying the generic memory regions which can be;
  * - Code section;
  * - Read-only data section;
+ * - Init code section, if applicable
  * - Coherent memory region, if applicable.
  */
 
index a8df5bad368a763eaea35666513d142d88f315c0..276f7801caab1b7c0aa45cfb69cbb90c4531daff 100644 (file)
@@ -273,3 +273,14 @@ endif
     include ${IMG_PARSER_LIB_MK}
 
 endif
+
+# RECLAIM_INIT_CODE can only be set when LOAD_IMAGE_V2=2 and xlat tables v2
+# are used
+ifeq (${RECLAIM_INIT_CODE}, 1)
+    ifeq (${LOAD_IMAGE_V2}, 0)
+        $(error "LOAD_IMAGE_V2 must be enabled to use RECLAIM_INIT_CODE")
+    endif
+    ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
+        $(error "To reclaim init code xlat tables v2 must be used")
+    endif
+endif